<?php
/**
 * App 首页 - 金刚区 图标管理
 *
 * Class ControllerExtensionModulePanxAppIconLink
 */
class ControllerExtensionModulePanxAppIconLink extends Controller
{
    /**
     * 扩展 CODE = 文件名  - extension 表
     */
    const EXTENSION_CODE = 'panx_app_icon_link';

    /**
     * 模块 CODE - module / layout_module / setting 表
     *
     * @since php5.6 - 5.6 之后常量可以使用标量进行表达示运算， 7.1 后常量可以私有
     * @link http://php.net/manual/en/language.oop5.constants.php
     */
    const MODULE_CODE = 'module_'. self::EXTENSION_CODE;

    /**
     * 模块 CODE - setting 表用于判断扩展状态文字显示的 key
     *
     * @see \ControllerStartupStartup::index
     * @see \ControllerExtensionExtensionModule::getList
     */
    const MODULE_STATUS = self::MODULE_CODE . '_status';
    const MODULE_STATUS_ON = 1;
    const MODULE_STATUS_OFF = 0;

    /**
     * 路由模块修改页面
     */
    const ROUTE_EXTENSION_MODULE = 'extension/module/' . self::EXTENSION_CODE;
    /**
     * 路由扩展市场页面
     */
    const ROUTE_MARKET_EXTENSION = 'marketplace/extension';

    /** @var Loader $loader */
    protected $loader;

    /** @var ModelSettingSetting $settingModel */
    protected $settingModel;

    /** @var ModelSettingModule $settingModuleModel */
    protected $settingModuleModel;

    private $error = [];

    const NO_IMAGE_PNG = 'no_image.png';
    
    const LOCALE_ICONS_MAP = 'locale_icons_map';
    
    /**
     * ControllerExtensionModulePanxAppIconLink constructor.
     *
     * @param $registry
     *
     * @throws Exception
     */
    public function __construct($registry)
    {
        parent::__construct($registry);

        $this->loader = $this->load;
        $this->loader->language(self::ROUTE_EXTENSION_MODULE);

        $this->settingModel = $this->loadModel('setting/setting');
        $this->settingModuleModel =  $this->loadModel('setting/module');
    }

    /**
     * @throws Exception
     */
    public function index()
    {
        if ($this->isPostAndValidated()) {
            return $this->storeOrUpdate();
        } else {
            return $this->toViewCreateOrEdit();
        }
    }

    /**
     * @return bool
     */
    private function isPostAndValidated()
    {
        return $this->isRequestMethod('POST') && $this->validate();
    }

    /**
     * @throws Exception
     */
    private function toViewCreateOrEdit()
    {
        $data = $this->viewCreateEditCommonData();

        if ($this->isToViewCreate()) {
            $data += $this->viewCreateData();
        } else {
            $data += $this->viewEditData();
        }

        $this->response->setOutput($this->load->view(self::ROUTE_EXTENSION_MODULE, $data));
    }

    /**
     * @return bool
     */
    private function isToViewCreate()
    {
        return $this->isRequestMethod('GET') && (! isset($this->request->get['module_id']));
    }


    /**
     * 扩展列表页面 URL
     *
     * @return string
     */
    private function extensionModulePageUrl()
    {
        return $this->url->link(self::ROUTE_MARKET_EXTENSION, 'type=module');
    }

    /**
     * @return array
     * @throws Exception
     */
    private function viewEditData()
    {
        $module_id = $this->requestGet('module_id');
        /**
         * @var array $module_setting - module 表 setting 列的 json 数组
         */
        $module_setting = $this->settingModuleModel->getModule($module_id);

        $action_data = [
            'action'     => $this->url->link(self::ROUTE_EXTENSION_MODULE, 'module_id=' . $module_id),
        ];

        $token_data = [
            'user_token' => $this->session->data['user_token']
        ];

        return $module_setting + $action_data + $token_data;
    }

    /**
     * @return array
     * @throws Exception
     */
    private function viewCreateData()
    {
        return [
            'action' => $this->url->link(self::ROUTE_EXTENSION_MODULE),
        ];
    }


    /**
     * @return array|mixed
     *
     * @throws Exception
     */
    private function viewCreateEditCommonData()
    {
        $layout = $this->adminLayoutData();

        /** @var ModelDesignBanner $banner */
        $banner = $this->loadModel('design/banner');
        /** @var ModelLocalisationLanguage $language */
        $language = $this->loadModel('localisation/language');

        $form_selections = [
            'banners'     => $banner->getBanners(),
            'languages'   => $language->getLanguages(),
        ];

        $twig_extends = $this->twigExtends();

        return $layout + $form_selections + $twig_extends;
    }

    /**
     * 加载后台布局框架
     *
     *
     * @return array
     */
    private function adminLayoutData()
    {
        return [
            // frames
            'header'      => $this->load->controller('common/header'),
            'column_left' => $this->load->controller('common/column_left'),
            'footer'      => $this->load->controller('common/footer'),

            // cancel btn href
            'cancel' => $this->extensionModulePageUrl(),
        ];
    }


    /**
     * @throws Exception
     */
    private function storeOrUpdate()
    {
        $setting = $this->request->post;
        
        $setting = $this->deleteIconsIndexKey($setting);
        
        /**
         * 注意 POST 中的 status 一定是 1，在设计布局（如是 0 依然可选）选中后，前端才会显示出现
         */
        if ($this->requestGet('module_id')) {
            $this->settingModuleModel->editModule($this->requestGet('module_id'), $setting);
        } else {
            $this->settingModuleModel->addModule(self::EXTENSION_CODE, $setting);
        }

        $this->operateSessionSuccess();

        $this->response->redirect($this->extensionModulePageUrl());
    }


    private function operateSessionSuccess()
    {
        $this->session->data['success'] = $this->language->get('text_success');
    }

    /**
     * 后台模块管理 -> 点击 + 号时安装
     *
     * @used-by \ControllerExtensionExtensionModule::install
     */
    public function install()
    {
        // 格式必须 module_{{ code }}_status， 功能模板列表中的 启用 / 禁用 状态文字才能正常显示
        $this->settingModel->editSetting( self::MODULE_CODE, [
            self::MODULE_STATUS => self::MODULE_STATUS_ON
        ]);

        // 框架没有 reload config 的值，手动改成状态启用
        $this->config->set(self::MODULE_STATUS, self::MODULE_STATUS_ON);
    }

    /**
     * 后台模块管理 -> 点击 - 号时卸载
     *
     * @used-by \ControllerExtensionExtensionModule::uninstall()
     * @throws Exception
     */
    public function uninstall()
    {
        $this->settingModel->deleteSetting( self::MODULE_CODE);

        // 框架没有 reload config 的值，手动改成状态禁用
        $this->config->set(self::MODULE_STATUS, self::MODULE_STATUS_OFF);

        $this->cleanUserGroupPermission();
    }

    /**
     * 框架不会自动删除权限，需要手动清理
     *
     * @throws Exception
     */
    private function cleanUserGroupPermission()
    {
        /** @var \Cart\User $user */
        $user = $this->user;

        /** @var int $user_group_id */
        $user_group_id = $user->getGroupId();

        /** @var ModelUserUserGroup $userGroup */
        $userGroup = $this->loadModel('user/user_group');
        $userGroup->removePermission($user_group_id, ModelUserUserGroup::PERMISSION_KEY_ACCESS, self::ROUTE_EXTENSION_MODULE);
        $userGroup->removePermission($user_group_id, ModelUserUserGroup::PERMISSION_KEY_MODIFY, self::ROUTE_EXTENSION_MODULE);
    }

	protected function validate()
    {
		if (!$this->user->hasPermission('modify', 'extension/module/store')) {
			$this->error['warning'] = $this->language->get('error_permission');
		}

		return !$this->error;
	}

    /**
     * @param string $filename
     * @param int $width
     * @param int $height
     * @param bool $placeholder
     *
     * @return string
     * @throws Exception
     */
    private function resizeImage($filename = null, $width = 100, $height = 100, $placeholder = true)
    {
        /** @var ModelToolImage $toolImage */
        $toolImage = $this->loadModel('tool/image');

        return $toolImage->resize($filename, $width, $height, $placeholder);
    }

    /**
     * @return Closure
     */
    private function resizeImageFn()
    {
        // 直接返回 [$this, 'func'] 也可以，但这样 IDE 无法索引函数，不利于重构
        return function () {
            return call_user_func_array([$this, 'resizeImage'], func_get_args());
        };
    }

    /**
     * @return array
     */
    private function twigExtends()
    {
        return [
            // twig usage: {{ thumbPlaceholder() }}  {{ thumbPlaceholder(other.deep.key, 20, 30) }}
            \Template\Twig::DATA_KEY_FNS => [
                new Twig_SimpleFunction('thumbPlaceholder', $this->resizeImageFn())
            ],
            // twig usage: {{ some_var | thumbPlaceholder }} or {{ some_var | thumbPlaceholder(param2, param3, ...) }}
            \Template\Twig::DATA_KEY_FILTERS => [
                new Twig_SimpleFilter('thumbPlaceholder', $this->resizeImageFn())
            ],
        ];
    }

    /**
     * 直接在 twig 里用 filter 即可
     *
     * @return string
     * @throws Exception
     */
    protected function thumbPlaceholder()
    {
        return $this->resizeImage(null);
    }
    
    /**
     * 前端排序好，直接存成数组
     *
     * @param array $setting
     * @return array
     */
    private function deleteIconsIndexKey(array $setting)
    {
        foreach ($setting[self::LOCALE_ICONS_MAP] as $locale => $icons) {
            $setting[self::LOCALE_ICONS_MAP][$locale] = array_values($icons);
        }
        
        return $setting;
    }

    public function categories(){
        $this->load->model('catalog/category');
        $data['categories'] = array();

        $filter_data = array(
            'sort'  => 'name',
            'order' => 'ASC',
        );

        $category_total = $this->model_catalog_category->getTotalCategories();

        $results = $this->model_catalog_category->getCategories($filter_data);

        foreach ($results as $result) {
            $data['categories'][] = array(
                'category_id' => $result['category_id'],
                'name'        => $result['name'],
            );
        }

        $this->responseOK($data);
    }
}